home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c)Copyright 1992-1997 Obvious Implementations Corp. Redistribution and
- * use is allowed under the terms of the DICE-LICENSE FILE,
- * DICE-LICENSE.TXT.
- */
- /*
- ** $Id: VSuckExamples.c,v 30.0 1994/06/10 18:09:36 dice Exp $
- **
- ** Hack of early VSuck to extract examples for testing.
- **
- ** (C) Copyright 1992, Obvious Implementations, All Rights Reserved
- */
- #define D(x) ;
- #define D1(x) ;
- #define D2(x) ;
- #define LINE_WIDTH 77 // So text won't wrap on 640 pixel wide screens
- #define MAX_PARAGRAPH 8000 // Yes... build that same limitation in.
-
- #define MIN_INDENT 4
- #define BODY_INDENT 8
- #define OPTION_INDENT 12
- #define EXAMPLE_INDENT 4 // Extra bytes past normal indent
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define unless(x) if(!(x))
- #define CR 13
- #define LF 10
- #define FF 12
- #define TAB 9
-
- /*******************************************************************************
- ** Globals
- */
- FILE *outfile; // FP for final output
-
- char allspaces[] =" ";
- char allhash[] ="################################################################################";
- char filename[] ="**INVALID***********************************************************************";
- char filename_nopath[] ="**INVALID*************************";
- char *pathname;
- char *examplename=0;
- char outbuf[LINE_WIDTH+3]; // Leave room for CR,LF,NULL
- char formatbuf[MAX_PARAGRAPH]; // Yes... build the same limitation in.
- char indenttext[LINE_WIDTH+3]; // For text in the left margin
- char indenttextvalid=0; // -option This is an option
-
- int bodyindent =BODY_INDENT;
- int optionindent =OPTION_INDENT;
- int indent =0;
-
- char *startinp; // Start of input
- register char *inp; // Walking input pointer
-
- int enum_val=0; // For @ENUM auto-counting
-
-
-
- /*******************************************************************************
- ** Prototypes
- */
- FilterCR(register char *leading);
- void ProcessFile();
- void putn(char *string,char terminator);
- void FormatParagraph(int slen,char *prestring);
- int CollectParagraph(void);
-
-
- /******************************************************************************/
- main(int argc,char *argv[])
- {
- FILE *infile;
- long insize;
-
- if (argc < 3 || ( argc == 2 && *argv[1]=='?' ) ) {
- printf("VSuckExamples <infile> <outdir> [example_name]\n");
- printf("; Extract examples from Ventura. Use for compile-checking.\n");
- exit(5);
- }
-
- D2(printf("Argc=%d, Arg1=%s, Arg2=%s\n",argc,argv[1],argv[2]));
-
- unless( infile=fopen(argv[1],"r" ) ) {
- printf("Error: Can't read \"%s\"\n",argv[1]);
- exit(10);
- }
- outfile=0;
- pathname=argv[2];
-
- if( argc == 4 ) {
- examplename=argv[3];
- printf("Extracting only example %s\n", examplename);
- }
-
- /*
- unless( outfile=fopen(argv[2],"w" ) ) {
- printf("Error: Can't write to \"%s\"\n",argv[2]);
- fclose(infile);
- exit(10);
- }
- */
-
- inp=0;
- fseek(infile,0,2);
- if( insize=ftell(infile) )
- {
- fseek(infile,0,0);
- if ( inp=malloc( insize+4 ) )
- {
- if ( insize==fread( inp,1,insize,infile ) )
- {
- inp[insize] =0; // Lots of space for sloppy code
- inp[insize+1]=0; // to read past without harm
- inp[insize+2]=0;
- inp[insize+3]=0;
- }
- else
- {
- printf("Error: Can't read \"%s\"\n",argv[1]);
- free( inp );
- inp=0;
- }
- }
- else
- {
- printf("Error: Out of memory (%ld bytes required)\n",insize+2);
- }
- }
-
- startinp=inp;
- if( inp ) {
- FilterCR(inp); // Nuke all CR's
- ProcessFile();
- free( startinp );
- }
-
- fclose( infile );
- if (outfile)
- fclose( outfile );
- printf("Exiting. Have a _very_ nice day.\n");
- }
-
-
- /*******************************************************************************
- ** Misc utility functions
- */
- // Like puts, put terminates at given character
- void putn(char *string,char terminator)
- {
- char *temp;
-
- temp=strchr(string,terminator);
- if (temp)
- fwrite(string,temp-string+1,1,stdout);
- }
-
- // Like strnlen, but counts to given character
- int strlenc(s,c)
- const char *s;
- char c;
- {
- const char *b = s;
-
- while (*s != c)
- ++s;
-
- return(s - b);
- }
-
- // Given start and current, count newlines to come up with a line number
- // !!! TODO: Add cache
- int ErrorLine(char *start, char *current)
- {
- int linenum =1;
-
- for(;start < current; start++)
- if ( *start==LF )
- linenum++;
-
- return(linenum);
- }
-
- // Do in-place removal of CR
- FilterCR(register char *leading)
- {
- register char *trailing=leading;
- register char c;
-
- while( c=*leading++ )
- {
- if (c != CR)
- *trailing++=c;
- }
- *trailing=0;
- trailing++;
- *trailing=0;
- trailing++;
- *trailing=0;
- trailing++;
- *trailing=0;
- trailing++;
- }
-
- /*******************************************************************************
- ** @ Functions
- */
-
- char *MAJOR_HEADING() // Set filename for result file
- {
- int len;
- char *temp;
- char c;
-
- len=CollectParagraph();
-
- if (temp=strchr(formatbuf,',')) // Use only first item of a multiple
- *temp=0; // function example
-
- len = strlen( formatbuf ); // Recalculate length
-
- if (len < LINE_WIDTH-10 ) {
- strcpy(filename, pathname);
-
- if( strlen(pathname) ) {
- c=pathname[strlen(pathname)-1];
- if (!( c==':' || c=='/' ))
- strcat(filename, "/");
- }
- strcat(filename, formatbuf);
- strcpy(filename_nopath, formatbuf);
- strcat(filename, ".c");
- strcat(filename_nopath, ".c");
- }
- else {
- strcpy(filename, pathname);
- strcat(filename, "/");
- strcat(filename, "** INVALID **");
- }
- }
-
- char *EXAMPLE()
- {
- if( examplename )
- if( strcmp( examplename, filename_nopath ) ) {
- CollectParagraph();
- return(0);
- }
-
- unless( outfile=fopen(filename,"w" ) ) {
- printf("Error: Can't write to \"%s\"\n",filename);
- return(0);
- }
- printf("Processing file \"%s\"\n",filename);
-
- FormatParagraph(CollectParagraph(),"");
-
- fclose(outfile);
- outfile=0;
- }
-
- int CollectParagraph()
- {
- int i=0;
-
- while( *inp )
- {
- if ( (*inp==LF) && (*(inp+1)==LF) ) // Two LF's signal end of para
- break;
-
- if ( *inp==CR ) {
- printf("Error: File must not contain CR's\n");
- break;
- }
-
- if ( i > (MAX_PARAGRAPH-100) ) {
- printf("Error: Paragraph too large!\n");
- break;
- }
-
- // Escape double <<brackets>>. Skip single <brackets>
- //
- if ( inp[0] == '<' && !(inp[1] == '<') ) {
- if ( inp[1]=='R' && inp[2]=='>' )
- {
- formatbuf[i++]=LF;
- if ( inp[3] == '\n' )
- inp++;
- inp += 3;
- }
- else {
- while( *inp && !(*inp=='>') )
- inp++;
- if (*inp)
- inp++; // Skip trailing >
- }
- }
- else if ( inp[0] == '<' && inp[1] == '<' )
- formatbuf[i++]='<',inp += 2;
- else if ( inp[0] == '>' && inp[1] == '>' )
- formatbuf[i++]='>',inp += 2;
- else if ( *inp == LF )
- formatbuf[i++]=' ',inp++;
- else
- formatbuf[i++]=*inp,inp++;
- }
- formatbuf[i]=0;
- formatbuf[i+1]=0;
- formatbuf[i+2]=0;
- formatbuf[i+3]=0;
-
- return(i);
- }
-
- void FormatParagraph(int slen,char *prestring)
- {
- int pos=0;
- int scan=0;
- int perline= LINE_WIDTH + 1 - strlen(prestring) - indent;
- int i;
-
- D1(printf("FormatParagraph. Slen=%d, prestring=%s\n", slen, prestring));
- D2(printf("%s", formatbuf));
-
- // Process normal text paragraph. Wrap words, nuke spaces at start
- // of line, etc. Handle <R>, grumble.
- while ( pos < slen )
- {
-
- // If there is a newline within the current line range, pump out
- // that string. Else set scan to just past end of line (or EOF)
- // and work backwards to word-wrap.
- scan=0;
- for (i=0; i < perline; i++)
- {
- if ( !formatbuf[pos+i] )
- break;
- if ( formatbuf[pos+i] == '\n' )
- {
- scan = pos+i+1; // Include linefeed
- D(printf("Newline found at %d\n",i));
- break;
- }
- }
-
- if( !scan )
- {
- // Skip leading spaces
- while ( formatbuf[pos]==' ' )
- pos++;
- if ( pos >= slen )
- break;
-
- scan = pos + perline; // Just past end of line
-
- if ( scan > slen)
- scan = slen; // Set to EOF
-
- // Scan backwards for NULL, LF, space separator or start of line
- while( scan > pos && formatbuf[scan] && formatbuf[scan] != ' ' )
- scan--;
-
- D(printf("Word-wrapped to %d bytes\n",scan-pos));
-
- if (pos == scan)
- printf("ERROR: Huge word (near line %d)\n",ErrorLine(startinp,inp));
- }
-
- if ( indenttextvalid )
- fwrite(indenttext,indent,1,outfile) , indenttextvalid=0;
- else
- fwrite(allspaces,indent,1,outfile);
-
- fprintf(outfile,prestring);
- fwrite(&formatbuf[pos],scan-pos,1,outfile);
- if ( formatbuf[scan-1] != '\n' )
- fprintf(outfile,"\n");
-
- pos = scan;
- }
- fprintf(outfile,"\n");
- }
-
-
- /*******************************************************************************
- ** @ Function tables & flags
- */
- #define ATSKIP 4 // Longs per atstuff entry
-
- #define AF_OPT 0x0001 // Option indenting
- #define AF_BODY 0x0002 // Body indenting
- #define AF_NOFLUSH 0x0004 // Disable flush before next @COMMAND
-
- char *(*atstuff[])()={
- "@MAJOR HEADING", MAJOR_HEADING, AF_BODY, 0,
- "@EXAMPLE", EXAMPLE, AF_OPT, 0,
- "@WIDEEXAMPLE", EXAMPLE, AF_OPT, 0,
- "@EXAMPLE_LIB", EXAMPLE, AF_OPT, 0,
- 0, 0, 0, 0,
- };
-
- /*******************************************************************************
- ** Processfile. Until reaching a null, scan the input file for
- ** @XXX keywords. Executue @ function, or print warning and keep
- ** scanning.
- */
- void ProcessFile()
- {
- int j;
- int atindex;
-
- D(printf("ProccessFile: outfile=%lx, inp=%lx\n",outfile,inp));
-
- while( *inp )
- {
- if (*inp == LF)
- *inp++;
- else if (*inp == CR)
- {
- printf("Error: File must not contain CR's\n");
- break;
- }
- else if (*inp == '@')
- {
- /*
- ** Find matching @ command
- */
- for( atindex=0; atstuff[atindex]; atindex += ATSKIP)
- {
- if( !strncmp(atstuff[atindex], inp, strlen(atstuff[atindex])) )
- break;
- }
-
- /*
- ** Execute @ command, if any. Else flush any pending line.
- */
- if( !atstuff[atindex] )
- {
- // Skip to next signifcant thing
- inp++;
- while( *inp && !(*inp=='@') && !(inp[0]==LF && inp[1]==LF) )
- inp++;
- }
- else{
- D1( printf("Matched tag: %s\n",atstuff[atindex]) );
-
- while( *inp && !(*inp=='=') ) // Skip to '='
- inp++;
- unless( inp[1]==' ' && inp[2])
- {
- printf("Warning: badly formatted @ tag or no example (%d)\n",ErrorLine(startinp,inp));
- while( *inp && !(*inp=='@') && !(inp[0]==LF && inp[1]==LF) )
- inp++;
- }
- else {
- inp += 2;
-
- for( j=0; j<LINE_WIDTH+2; j++)
- outbuf[j]=' ';
- outbuf[j+1]=0;
-
-
- // if( atstuff[atindex+3] )
- // indent = atstuff[atindex+3];
-
- if( indenttextvalid )
- printf("Warning: Left margin text lost (%d)\n",ErrorLine(startinp,inp));
-
- (*atstuff[atindex+1])(inp);
- }
- }
- }
- else{
- FormatParagraph(CollectParagraph(),"");
- }
- }
- D(printf("End ProccessFile: outfile=%lx, inp=%lx\n",outfile,inp));
- }
-
-